package com.bii.gelapp;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class CompareActivity extends Activity {

	Button btSave, btPrev, btCalculate, btCompare, btSaveSettings;
	ImageView ivImage;
	Bitmap originalBmp, activeBmp;
	public Bitmap colorBmp;
	public static ArrayList<ConnectedComponent> componentlist = new ArrayList<ConnectedComponent>();
	public static ArrayList<ConnectedComponent> markerlist = new ArrayList<ConnectedComponent>();

	public static ArrayList markervalues;

	// to store hue average
	ArrayList hueaverages = new ArrayList();

	MarkerStandard mss;

	String origin;
	int indexlargest = 0;
	float largestheight = 0;
	float largestwidth = 0;

	Bitmap bmap;
	Mat drawmat;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// this is all a test, not full implementation
		super.onCreate(savedInstanceState);
		setContentView(R.layout.compareactivity);
		if (getIntent().hasExtra("origin")) {
			origin = getIntent().getStringExtra("origin");
		}
		// get component and markerlist
		ivImage = (ImageView) findViewById(R.id.ivImage);
		componentlist = (ArrayList<ConnectedComponent>) getIntent()
				.getSerializableExtra("componentlist");
		Log.d("tag1", "componentlist size: " + componentlist.size());
		markerlist = (ArrayList<ConnectedComponent>) getIntent()
				.getSerializableExtra("markerlist");
		//
		markervalues = null;
		markervalues = new ArrayList();
		Log.d("tag1", "size of markerlist = " + markerlist.size());
		Log.d("tag1", "markerlist size: " + markerlist.size());
		// byte[] byteArray = getIntent().getByteArrayExtra("BMP");
		// originalBmp = BitmapFactory.decodeByteArray(byteArray, 0,
		// byteArray.length);
		colorBmp = RotationActivity.colorBmp;
		// bmap = originalBmp;
		bmap = colorBmp;
		drawmat = new Mat(bmap.getHeight(), bmap.getWidth(), CvType.CV_8U);
		drawRectangles();

		mss = StartActivity.ms;
		final int listdifference;

		final ArrayList mssmarkerslist = mss.markerslist;

		Log.d("tag1", "size of mss = " + mssmarkerslist.size());
		if (mssmarkerslist.size() > markerlist.size()) {
			listdifference = mssmarkerslist.size() - markerlist.size();
		} else {
			listdifference = mssmarkerslist.size() - markerlist.size();
		}

		// compare average hue, used to get minimum
		final ArrayList compareaveragehuelist = new ArrayList();

		btPrev = (Button) findViewById(R.id.btPrev);
		btPrev.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (origin.equals("Segmentation")) {
					startActivity(new Intent(CompareActivity.this,
							SegmentationActivity.class));
				} else {
					startActivity(new Intent(CompareActivity.this,
							AutoActivity.class));
				}
			}
		});

		btSaveSettings = (Button) findViewById(R.id.btSaveSettings);
		btSaveSettings.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				SettingSaveDialog sd = new SettingSaveDialog(
						CompareActivity.this);
				sd.show();
			}
		});

		btCompare = (Button) findViewById(R.id.btCompare);
		btCompare.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				int lowestindex = 0;
				int minaveragehue = 0;

				Utils.bitmapToMat(bmap, drawmat);
				drawRectangles();
				if (markervalues.size() == 0) {

					for (int i = 0; i <= listdifference; i++) {

						ArrayList averagehuelist = new ArrayList();
						for (int j = 0; j < markerlist.size(); j++) {

							int[] msscolors = mss.getmarkers().get(j + i).color;
							int red = msscolors[0];
							int green = msscolors[1];
							int blue = msscolors[2];
							float[] hsv = new float[3];
							android.graphics.Color.RGBToHSV(red, green, blue,
									hsv);

							int horizontalmid = (markerlist.get(j).left + markerlist
									.get(j).right) / 2;
							// get center vertical
							int verticalmid = (markerlist.get(j).top + markerlist
									.get(j).bottom) / 2;
							int pixel = bmap.getPixel(horizontalmid,
									verticalmid);
							int redValue = Color.red(pixel);
							int blueValue = Color.blue(pixel);
							int greenValue = Color.green(pixel);
							float[] hsv1 = new float[3];
							android.graphics.Color.RGBToHSV(redValue,
									greenValue, blueValue, hsv1);
							// Log.i("HSV_H", "Hue=" + hsv1[0]);
							// Log.i("HSV_H", "Saturation=" + hsv1[1]);
							// Log.i("HSV_H", "Value=" + hsv1[2]);

							// int averageadd = (int) (hsv[0] - hsv1[0]);
							int averageadd = distance((int) hsv[0],
									(int) hsv1[0]);

							int averageaddfinal = averageadd * averageadd;
							Log.d("tag1", "marker: " + (j + i)
									+ " compare with " + "picture " + j + "="
									+ averageaddfinal);
							Log.d("tag1", "marker top: "
									+ markerlist.get(j).top + " standard top: "
									+ mss.getmarkers().get(j + i).top);
							Log.d("tag1", "----------");
							averagehuelist.add(averageaddfinal);

						}
						// can put inside first loop

						int sum = 0;
						for (int k = 0; k < averagehuelist.size(); k++) {
							sum += (Integer) averagehuelist.get(k);
						}
						int sqrtsum = (int) Math.sqrt(sum);
						compareaveragehuelist.add(sqrtsum);
						Log.d("tag1", "averagehue: " + sqrtsum);
						if (minaveragehue == 0) {
							minaveragehue = sqrtsum;
						} else if (sqrtsum < minaveragehue) {
							minaveragehue = sqrtsum;
							lowestindex = i;
							Log.d("tag1", "minimum avg: " + minaveragehue);
							Log.d("tag1", "minimum index to add: "
									+ lowestindex);
						} else {

						}
						Log.d("tag1", "final minimum avg: " + minaveragehue);
						Log.d("tag1", "final minimum index to add: "
								+ lowestindex);

					}

					for (int i = 0; i < markerlist.size(); i++) {

						int top = markerlist.get(i).top;
						int bottom = markerlist.get(i).bottom;
						int left = markerlist.get(i).left;
						int right = markerlist.get(i).right;

						int centerheight = (bottom + top) / 2;
						int centerwidth = (right + left) / 2;
						Point org = new Point(centerwidth, centerheight);

						MarkerConnectedComponent mcc = mss.getmarkers().get(
								i + lowestindex);
						int value = mcc.value;
						//add into markervalues the compared value
						markervalues.add(value);
						String valuedisplay = " " + value;
						int[] msscolors = mss.getmarkers().get(i + lowestindex).color;
						int red = msscolors[0];
						int green = msscolors[1];
						int blue = msscolors[2];

						Core.putText(drawmat, valuedisplay, org, 3, 1,
								new Scalar(red, green, blue), 5);
						Bitmap drawnbmp = Bitmap.createBitmap(drawmat.cols(),
								drawmat.rows(), Bitmap.Config.RGB_565);
						Utils.matToBitmap(drawmat, drawnbmp);

						//Bitmap resizedbmp = Bitmap.createScaledBitmap(drawnbmp,
						//		300, 300, true);
						//ivImage.setImageBitmap(resizedbmp);
						ivImage.setImageBitmap(drawnbmp);

					}
				} else {
					for (int i = 0; i < markerlist.size(); i++) {

						int top = markerlist.get(i).top;
						int bottom = markerlist.get(i).bottom;
						int left = markerlist.get(i).left;
						int right = markerlist.get(i).right;

						int centerheight = (bottom + top) / 2;
						int centerwidth = (right + left) / 2;
						Point org = new Point(centerwidth, centerheight);

						MarkerConnectedComponent mcc = mss.getmarkers().get(
								i + lowestindex);
						// int value = mcc.value;
						int value = (Integer) markervalues.get(i);
						String valuedisplay = " " + value;
						int[] msscolors = mss.getmarkers().get(i + lowestindex).color;
						int red = msscolors[0];
						int green = msscolors[1];
						int blue = msscolors[2];

						Core.putText(drawmat, valuedisplay, org, 3, 1,
								new Scalar(red, green, blue), 5);
						Bitmap drawnbmp = Bitmap.createBitmap(drawmat.cols(),
								drawmat.rows(), Bitmap.Config.RGB_565);
						Utils.matToBitmap(drawmat, drawnbmp);

						//Bitmap resizedbmp = Bitmap.createScaledBitmap(drawnbmp,
						//		300, 300, true);
						//ivImage.setImageBitmap(resizedbmp);
						ivImage.setImageBitmap(drawnbmp);

					}
				}

			}
		});

		btCalculate = (Button) findViewById(R.id.btCalculate);
		btCalculate.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				// Intent goToNextActivity = new Intent(CompareActivity.this,
				// CalculateActivity.class);

				Intent goToNextActivity = new Intent(CompareActivity.this,
						CalculateActivity2.class);
				// goToNextActivity.putParcelableArrayListExtra("componentlist",
				// (ArrayList<? extends Parcelable>) componentlist);
				// goToNextActivity.putExtra("componentlist", componentlist);
				// byte[] bytes;
				// bytes = compressImage(colorBmp);
				// byte[] bytes1;
				// bytes1 = compressImage(originalBmp);
				// goToNextActivity.putExtra("BMP1", bytes1);
				// goToNextActivity.putExtra("BMP", bytes);

				if (markervalues.size() == 0) {
					for (int i = 0; i < mss.getmarkers().size(); i++) {
						markervalues.add(mss.getmarkers().get(i).value);
					}
				}

				goToNextActivity.putExtra("componentlist", componentlist);

				goToNextActivity.putExtra("markerlist", markerlist);
				goToNextActivity.putExtra("markervalues", markervalues);

				/*
				 * if (markervalues.size() != 0) {
				 * 
				 * } else {
				 * 
				 * goToNextActivity.putExtra("markervalues", markervalues); }
				 */

				startActivity(goToNextActivity);

			}
		});

		// sort vertically
		Collections.sort(componentlist, new Comparator<ConnectedComponent>() {
			@Override
			public int compare(ConnectedComponent cc1, ConnectedComponent cc2) {
				return cc1.top - cc2.top;
			}
		});

		// sort horizontally
		Collections.sort(componentlist, new Comparator<ConnectedComponent>() {
			@Override
			public int compare(ConnectedComponent cc1, ConnectedComponent cc2) {
				return cc1.left - cc2.left;
			}
		});

		// for(int i = 0; i < markerlist.size(); i++)
		// {
		// markerlist.remove(i);
		// }
		// for (int i = markerlist.size() - 1; i >= 0; i--) {
		// componentlist.remove(i);
		// }

		drawRectangles();
		//Bitmap drawnbmp = Bitmap.createBitmap(drawmat.cols(), drawmat.rows(),
		//		Bitmap.Config.RGB_565);
		Utils.matToBitmap(drawmat, activeBmp);

		//Bitmap resizedbmp = Bitmap.createScaledBitmap(drawnbmp, 300, 300, true);
		//ivImage.setImageBitmap(resizedbmp);
		ivImage.setImageBitmap(activeBmp);

		ivImage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent goToNextActivity = new Intent(getApplicationContext(),
						CompareFullScreenActivity.class);
				goToNextActivity.putExtra("markerlist", markerlist);
				if (markervalues.size() != 0) {
					goToNextActivity.putExtra("markervalues", markervalues);
				} else {
					for (int i = 0; i < mss.getmarkers().size(); i++) {
						markervalues.add(mss.getmarkers().get(i).value);
					}
					goToNextActivity.putExtra("markervalues", markervalues);
				}
				startActivity(goToNextActivity);
			}
		});

	}

	private void drawRectangles() {
		Utils.bitmapToMat(bmap, drawmat);
		for (int i = 0; i < componentlist.size(); i++) {
			Core.rectangle(drawmat, new Point(componentlist.get(i).left,
					componentlist.get(i).top), new Point(
					componentlist.get(i).right, componentlist.get(i).bottom),
					new Scalar(255, 0, 0), 2);
			// 11/8
			int top = componentlist.get(i).top;
			int bottom = componentlist.get(i).bottom;
			int left = componentlist.get(i).left;
			int right = componentlist.get(i).right;

			int centerheight = (bottom + top) / 2;
			int centerwidth = (right + left) / 2;
			Point org = new Point(centerwidth, centerheight);

			Core.putText(drawmat, "" + i, org, 3, 1, new Scalar(0, 0, 255), 5);
			// Core.putText(img, text, org, fontFace, fontScale, color);
		}
		for (int i = 0; i < markerlist.size(); i++) {
			Core.rectangle(drawmat, new Point(markerlist.get(i).left,
					markerlist.get(i).top), new Point(markerlist.get(i).right,
					markerlist.get(i).bottom), new Scalar(255, 255, 0), 2);
			int top = markerlist.get(i).top;
			int bottom = markerlist.get(i).bottom;
			int left = markerlist.get(i).left;
			int right = markerlist.get(i).right;

			int centerheight = (bottom + top) / 2;
			Point org = new Point(right, centerheight);

			Core.putText(drawmat, "" + i, org, 3, 1, new Scalar(0, 255, 0), 5);
		}
		Bitmap drawnbmp = Bitmap.createBitmap(drawmat.cols(), drawmat.rows(),
				Bitmap.Config.RGB_565);
		Utils.matToBitmap(drawmat, drawnbmp);
		activeBmp = drawnbmp;
		//Bitmap resizedbmp = Bitmap.createScaledBitmap(drawnbmp, 300, 300, true);
		//ivImage.setImageBitmap(resizedbmp);
		ivImage.setImageBitmap(activeBmp);

	};

	private static int distance(int h1, int h2) {
		int d = Math.abs(h1 - h2);
		if (d < (360 - d))
			return d;
		else
			return (360 - d);
	}

	public byte[] compressImage(Bitmap image) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.PNG, 0, stream);
		byte[] bytes = stream.toByteArray();
		return bytes;
	}
}
